package com.walter.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.walter.common.CommonQuery;
import com.walter.entity.Menu;
import com.walter.entity.RoleMenu;
import com.walter.exception.LogicException;
import com.walter.mapper.MenuMapper;
import com.walter.mapper.RoleMenuMapper;
import com.walter.model.vo.MenuVO;
import com.walter.util.Kv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ：ch
 * @date ：Created in 2021/5/25
 * @description：
 * @modified By：
 * @version: 1.0
 */
@Service
@Slf4j
public class MenuService {
    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Value("${built-in adminRole}")
    private String adminRole;

    @Autowired
    private RoleService roleService;

    @Transactional // todo
    public Integer initMenus(){
        //menus todo
        //roleMenus
        Integer retVal = 0;
        List<Menu> menuList = menuMapper.selectList(null);
        if (CollUtil.isNotEmpty(menuList)){
            Integer adminRoleId = roleService.findByName(adminRole).getId();
            List<Integer> menuIds = menuList.stream().map(menu -> menu.getId()).collect(Collectors.toList());
            roleMenuMapper.deleteByMap(Kv.by(RoleMenu.ROLE_ID,adminRoleId));
            retVal += roleMenuMapper.addInBatch(Kv.by("menuList",menuIds).set("roleId",adminRoleId).set("createTime",new Date()));
        }
        return retVal;
    }

    //add
    @Transactional
    public Boolean add(Menu menu){
        List<Menu> menus = menuMapper.selectByMap(Kv.by(Menu.NAME,menu.getName())); //去重
        if (CollectionUtil.isNotEmpty(menus)){
            log.info("menu_name = {} is repeated when adding a menu",menu.getName());
            throw new LogicException("菜单名称不能重复");
        }
        menuMapper.insert(menu.setCreateTime(new Date()));
        //admin has the all menus' auth
        Integer adminRoleId = roleService.findByName(adminRole).getId();
        roleMenuMapper.insert(new RoleMenu().setCreateTime(new Date()).setMenuId(menu.getId()).setRoleId(adminRoleId));
        return true;
    }

    //update
    @Transactional
    public Boolean update(Menu menu){
        Integer menuId = menu.getId();
        if (null == menuId)
            throw new LogicException("菜单id为空");
        EntityWrapper<Menu> entityWrapper = new EntityWrapper<>();
        entityWrapper.notIn(Menu.ID,menuId).eq(Menu.NAME,menu.getName());
        List<Menu> menus = menuMapper.selectList(entityWrapper);
        if (CollectionUtil.isNotEmpty(menus))
            throw new LogicException("菜单名称不能重复");
        return menu.setUpdateTime(new Date()).updateById();
    }

    //findOne
    public Menu findOne(Integer menuId){
        if (null == menuId) {
            log.info("menuId is null");
            throw new LogicException("菜单id为空");
        }
        Menu menu = menuMapper.selectById(menuId);
        if (null == menu){
            log.info("menu is null");
            throw new LogicException("id为" + menuId + "的菜单不存在");
        }
        return menu;
    }

    //find
    public List<MenuVO> find(CommonQuery query){
        List<MenuVO> retVal = menuMapper.find(BeanUtil.beanToMap(query));
        return retVal;
    }

    //deleteById
    @Transactional
    public Boolean deleteById(Integer menuId){
        Menu menu = this.findOne(menuId);
        if (null != menu.getPid()){
            Integer t1 = menuMapper.deleteById(menuId);
            log.info("delete sys_menu {} record",t1);
            Integer t2 = roleMenuMapper.deleteByMap(Kv.by(RoleMenu.MENU_ID,menuId));
            log.info("delete sys_role_menu {} record",t2);
            return true;
        }
        List<Menu> subMenus = menuMapper.selectByMap(Kv.by(Menu.PID,menuId));
        if (CollectionUtil.isEmpty(subMenus)) {
            Integer t1 = menuMapper.deleteById(menuId);
            log.info("delete sys_menu {} record",t1);
            Integer t2 = roleMenuMapper.deleteByMap(Kv.by(RoleMenu.MENU_ID,menuId));
            log.info("delete sys_role_menu {} record",t2);
            return true;
        }
        throw new LogicException("请先删除该菜单的所有子菜单");
    }
}
